package org.greatlogic.gwtfilereaderwidget.client.itunes;

import org.greatlogic.gwtfilereaderwidget.client.itunes.ITunesEnums.EConjunction;
import org.greatlogic.gwtfilereaderwidget.client.itunes.ITunesEnums.ETrackKeyType;
import org.greatlogic.gwtfilereaderwidget.client.itunes.ITunesEnums.EOperator;

class Condition {
//--------------------------------------------------------------------------------------------------
private ConditionParentNode _currentConditionParentNode;
private ConditionParentNode _topConditionParentNode;
//--------------------------------------------------------------------------------------------------
Condition() {
  _topConditionParentNode = new ConditionParentNode();
  _currentConditionParentNode = _topConditionParentNode;
} // Condition()
//--------------------------------------------------------------------------------------------------
private Condition addNode(final int openParens, final int closeParens,
                          final ConditionLeafNode leafNode) throws ITunesException {
  if (openParens > 0 && closeParens > 0) {
    throw new ITunesException("Cannot specify both open and close parentheses");
  }
  for (int openParenCount = 0; openParenCount < openParens; ++openParenCount) {
    ConditionParentNode newParentNode = new ConditionParentNode();
    _currentConditionParentNode.addChildNode(newParentNode);
    _currentConditionParentNode = newParentNode;
  }
  _currentConditionParentNode.addChildNode(leafNode);
  for (int closeParenCount = 0; closeParenCount < closeParens &&
                                _currentConditionParentNode.getParentNode() != null; ++closeParenCount) {
    _currentConditionParentNode = _currentConditionParentNode.getParentNode();
  }
  return this;
} // addNode()
//--------------------------------------------------------------------------------------------------
Condition addNode(final int openParens, final int closeParens, final EConjunction conjunction,
                  final ETrackKeyType keyType, final EOperator operator) throws ITunesException {
  return addNode(openParens, closeParens, new ConditionLeafNode(conjunction, keyType, operator));
} // addNode()
//--------------------------------------------------------------------------------------------------
Condition addNode(final int openParens, final int closeParens, final EConjunction conjunction,
                  final ETrackKeyType keyType, final EOperator operator, final long... operands)
  throws ITunesException {
  return addNode(openParens, closeParens, new ConditionLeafNode(conjunction, keyType, operator,
                                                                operands));
} // addNode()
//--------------------------------------------------------------------------------------------------
Condition addNode(final int openParens, final int closeParens, final EConjunction conjunction,
                  final ETrackKeyType keyType, final EOperator operator, final String... operands)
  throws ITunesException {
  return addNode(openParens, closeParens, new ConditionLeafNode(conjunction, keyType, operator,
                                                                operands));
} // addNode()
//--------------------------------------------------------------------------------------------------
boolean evaluate(final Track track) throws ITunesException {
  return _topConditionParentNode.evaluate(track);
} // evaluate()
//--------------------------------------------------------------------------------------------------
@Override
public String toString() {
  return _topConditionParentNode.toString();
} // toString()
//--------------------------------------------------------------------------------------------------
}